const https = require('https');
const urlQuery = require("querystring");
const redis = require("../../redis/redis-client");
const axios = require("axios");
const puppeteer = require("puppeteer");
// 引入 nodemailer 模块
const nodemailer = require("nodemailer");

let timer = null

// 创建一个 SMTP 传输对象
const transporter = nodemailer.createTransport({
  service: "qq", // 邮箱服务名
  auth: {
    user: "1@qq.com", // 邮箱账号
    pass: "" // 邮箱授权码
  }
});
// 设置邮件选项
const mailOptions = {
  from: "1@qq.com", // 发件人邮箱
  to: "1@qq.com", // 收件人邮箱，可以是多个，用逗号分隔
  subject: "error", // 邮件主题
  text: "This is a test email from NodeMailer." // 邮件正文，纯文本格式
};


//使用 puppeteer.launch 启动 Chrome
(async function updateFn(currentI = 0, currentP = 1) {

  // 连接已打开的浏览器
  // let wsKey = await axios.get('http://localhost:21222/json/version');
  // const browser = await puppeteer.connect({
  //   browserWSEndpoint: wsKey.data.webSocketDebuggerUrl,
  //   defaultViewport: null,
  //   slowMo: 100,
  //   headless: true,
  //   timeout: 60000 * 5,
  // })


  // 打开新的浏览器
  const browser = await puppeteer.launch(
    {
      headless: true,
      // headless: false,
      defaultViewport: {
        width: 1920,
        height: 1080
      },
      slowMo: 100,
      args: [
        '--no-sandbox',
        '--disable-features=site-per-process',
        '--start-maximized'
      ],
      timeout: 60000
    },
  );

  const page = await browser.newPage();
  await page.goto("http://10.139.3.16/sainty/");

  page.setDefaultNavigationTimeout(60000 * 5); // 1 hour

  const sendM = (reason) => {
    // 使用 transporter 对象的 sendMail 方法发送邮件
    // transporter.sendMail({ ...mailOptions, text: reason + "" }, (error, info) => {
    // });
  }


  // 当前在第几页
  let currentPage = currentP;

  // 出库工作台的数据列表
  let inputWorkbenchList = [];

  // 新增的采购合同信息item
  let addList = [];

  // 被修改过的商品信息的合同id
  let changeGoods = [];

  //当前执行的条数
  let currentItem = currentI;

  //每条占滚动条比率
  let ScrollRatio = 0;

  // 总分页数
  let totalpages = 0;

  // 总条数
  let totalItem = 0;

  // 每次移动条数
  const count = 15;


  // 监听error
  process.on('unhandledRejection', async (reason, p) => {
    console.error('Unhandled Rejection at: Promise:zk', 'reason:', reason);
    // changeGoods = [];
    // 开启新一轮轮循
    if (timer) {
      clearTimeout(timer)
    }

    timer = setTimeout(async () => {
      timer = null;
      let cp = currentPage - 1
      await browser.close();
      updateFn()
      // await page.close();
      //  sendM(reason + "当前item" + cp * count + "当前页数" + cp)
    }, 5000);
  });

  const submitBtnEle = await page.$("input[id='LOGINSUBMIT']");
  if (submitBtnEle) {
    await submitBtnEle.click();
  }

  await page.waitForSelector(".menu-warp");
  const lineMenu = await page.$("a[title='仓储物流']");
  await lineMenu.click();

  const inputWorkbench = await page.$("a[title='成品入库工作台']");
  await inputWorkbench.click();

  const iframe = await page.waitForFrame((frame) => (frame.url().includes("InitValue.gtype")));

  if (iframe) {

    // 监听请求的响应的
    onPageList();

    await page.waitForTimeout(1000);

    // 输入入库运编号
    const inputIdEl = await iframe.$("input[name='storagebatchno']");
    await inputIdEl.type("G118", { delay: 20 });

    // // 点击展开
    // const developEl = await iframe.$("#UIA_purworkspaceQ__switchcss_ui-pane-collapsed");
    // await developEl.click();

    // 取消勾选只查待入库>0
    // const checkboxEl = await iframe.$("input[name='coropt#20']");
    // await checkboxEl.click();

    // // 签约日期取消
    // const dateEl = await iframe.$("input[name='odate.[from]']");
    // await dateEl.click();
    // await page.keyboard.press('Backspace');

    // const dateEl = await iframe.$("#UIA_purworkspaceQ_odateform .ui-input-combobtn");
    // await dateEl.click();
    // // 选择年
    // const dayClass = await iframe.$$("#YMSELECT .ui-input-combobtn");
    // await dayClass[0].click();

    // await iframe.$$eval("#LIST .label span", node => node.map((el) => {
    //   console.log(el.innerText);
    //   if (el.innerText == "2021") {
    //     el.click()
    //   }
    // }))
    // // 选择月
    // await dayClass[1].click();
    // await iframe.$$eval("#LIST .label span", node => node.map((el) => {
    //   console.log(el.innerText);
    //   if (el.innerText == "1") {
    //     el.click()
    //   }
    // }))
    // 选择日
    // await iframe.$$eval("#DAYSELECT td", node => node.map((el) => {
    //   console.log(el.innerText);
    //   if (el.innerText == "15") {
    //     el.click()
    //   }
    // }))
    // const selectedDay = await iframe.$("#DAYSELECT td.selectedday")
    // await selectedDay.click()

    // const NAVMONPREV = await iframe.$("#NAVMONPREV");

    // for (let i = 0; i < 6; i++) {
    //   await NAVMONPREV.click();
    // }
    // const day = await iframe.$("#DAYSELECT .bodyrow .day");
    // await day.click();

    // 点击查询
    const searchEl = await iframe.$("#UIA_purworkspaceQ_btn_wrefreshtbls");
    await searchEl.click();

    await page.waitForTimeout(3000);

  }

  // 方法区--------------------------------------------------------------


  //获取完成入库工作台列表后执行
  async function forList() {
    await page.waitForTimeout(2000);

    //计算比率
    var scrollHeight = await iframe.$eval(".ui-gridtable .ui-grid-bar", el => el.scrollHeight);

    ScrollRatio = scrollHeight / totalItem;

    // 移除监听采购订单合同列表
    page.removeListener('response');
    console.log("需要更新的addList", addList);

    onGoods();

    // redis.getString("enterCurrentPage").then(res => {
    //   if (res && res < totalpages) {
    //     currentPage = res;
    //     iframe.$eval(".ui-gridtable .ui-grid-bar", (el, { ScrollRatio, currentPage, count }) =>
    //       (el.scrollTop = ScrollRatio * currentPage * count),
    //       { ScrollRatio, currentPage, count }
    //     )
    //   }
    //   redis.getString("enterCurrentItem").then(res => {
    //     if (res && res < totalItem) {
    //       currentItem = res

    //       // redis.removeString("enterCurrentPage")
    //       // redis.removeString("enterCurrentItem")
    //     }
    //   })
    // })


    // -----------------------开始轮循点击采购合同---------------------------------
    await forClickId();
  }

  // 循环点击采购订单合同 结束后重新轮循获取入库工作台列表
  async function forClickId() {

    // 当前页面的合同id
    let div = await iframe.$$eval(".gtable tbody tr:not(.emptyrow) td:nth-child(2)", node => node.map((el) => el.innerText.trim()));
    console.log("div:", div);

    // 当前页面需要点击的元素
    let divId = await iframe.$$(".gtable tbody tr:not(.emptyrow) td:nth-child(2)");

    // 截取页面显示的count条记录
    if (currentPage < totalpages) {
      divId = divId.slice(0, count)
    }

    for (let i = 0; i < divId.length; i++) {
      console.log("当前索引：", i, "当前合同id", div[i]);
      let item = inputWorkbenchList.find(({ contractId }) => div[i] == contractId);

      if (item && item.goods.length == 0) {
        await divId[i].click({ clickCount: 2, delay: 100 });

        await page.waitForTimeout(3000);

        // 隐藏弹窗 影响点击事件
        // try {
        const tiptext = await iframe.$(".x-tiptext.ui-layer-frame");
        if (tiptext) await iframe.$eval(".x-tiptext.ui-layer-frame", node => node.style.display = "none");

        // } catch (error) {
        //   console.log(error);
        //   transporter.sendMail({ ...mailOptions, text: error + "隐藏弹窗的try catch" }, (error, info) => { });
        // }

        const childIframe = await page.waitForFrame((frame) => (frame.url().includes("InitValue.purordicode")));

        const purordcode = await childIframe.$(" input[name='purordcode']")

        if (purordcode) {
          const close = await page.$("#tabChangeUl li:last-child .icol-del3");

          await page.waitForTimeout(1000);
          await close.click()
        }
      }
      // 记录执行过的条数
      currentItem++;
      console.log("当前执行的条数", currentItem, "总条数：", totalItem, "当前滚动次数：", currentPage, "滚动总次数:", totalpages);
    }

    if (currentPage > totalpages) {
      // 使用 transporter 对象的 sendMail 方法发送邮件
      // transporter.sendMail({ ...mailOptions, text: "执行最后一页了" }, (error, info) => { });

      console.log("end---------inputWorkbenchList:");
      // 更新未同步的商品
      changeGoods.map((id) => {
        const index = inputWorkbenchList.findIndex(({ contractId }) => id == contractId);
        if (index > -1) {
          sendUpdateGoodsToServer({ goods: inputWorkbenchList[index].goods })
        }
      })

      // redis.removeString("enterCurrentPage")
      // redis.removeString("enterCurrentItem")

      changeGoods = [];
      // 开启新一轮轮循
      browser.close();
      setTimeout(() => {
        updateFn()
      }, 5000);
      return
    }

    if (currentPage <= totalpages) {
      // 执行完当前count条数 滚动翻页 继续执行
      // await iframe.waitForSelector(".ui-gridtable .ui-grid-bar");
      iframe.$eval(".ui-gridtable .ui-grid-bar", (el, { ScrollRatio, currentPage, count }) =>
        (el.scrollTop = ScrollRatio * currentPage * count),
        { ScrollRatio, currentPage, count }
      )

      currentPage++;
      await forClickId()
    }

  }

  // 监听采购合同点击
  function onGoods() {
    page.on("response", (response) => {
      if (response.status() == 200) {
        if (response.url().includes("27.15.20.G0.20.N9STJ.do.ui")) {

          // url query 参数转json
          const queryJson = urlQuery.parse(response.request().postData());

          // 商品信息的接口
          if (queryJson && queryJson.gcodeCuicode) {
            response.text().then(res => {
              // 解析字符串形的对象
              const resData = eval("(" + res + ")");
              // 存储的字段数组
              const fields = resData.fields;

              let goods = [];

              resData.rows.map((item) => {
                goods.push({
                  "warehousingType": getValueByNameId("gstockmode", item[1], fields),//入库登记方式
                  "transportId": item[2], //入库运编号
                  "clientOrderId": item[3],//客户订单号
                  "clientItemId": item[5], //客户货号
                  "goodsType": getValueByNameId("gtype", item[6], fields),//货物类型
                  "goodsName": item[7],//商品名称
                  "goodsDesc": item[8],//商品描述
                  "brand": item[12],//品牌
                  "customsDeclaration": item[13],//单独报关
                  "goodsCount": item[14],//签约数量
                  "goodsUnits": getValueByNameId("qtcunit", item[15], fields),//签约单位
                  // "purchasePrice": item[16],//采购单价
                  "amount": item[17],//金额
                  "deliveryDate": item[18],//交货日期
                  "deliveryAddress": getValueByNameId("deliveryplace", item[19], fields),//交货地址
                  "totalPackages": item[20], //包装件数 总件数
                  "packagesUnit": getValueByNameId("qtxunit", item[21], fields), //包装单位
                  "builtinNum": item[22], //内装数量
                  "exteriorNum": item[23], //外装数量
                  "roughWeight": item[24], //毛重
                  "roughWeightTotal": item[25], //毛重合计
                  "netWeight": item[26], //净重
                  "netWeightTotal": item[27], //净重合计
                  "packType": getValueByNameId("packtype", item[28], fields), //包装类型
                  "matrixingRatio": item[51], //换算比例
                  "total": item[52], //统计总数 总数量
                  "units": getValueByNameId("qtcunit", item[53], fields), //统计单位
                  "hsCode": item[54], //海关编码
                  "shippingMark": item[55], //分唛头
                  "remarks": item[56], //备注
                  "contractId": item[62].trim()
                });
              });

              // 如果有货品 把goods放入采购合同的goods里
              if (goods.length) {
                const item = inputWorkbenchList.find(({ contractId }) => contractId == goods[0].contractId);
                if (item) {
                  item.goods = goods;
                }
                // 要更新的商品信息
                console.log("要更新的当前商品信息的合同列表changeGoods:", changeGoods);

                // const index = changeGoods.findIndex((id) => goods[0].contractId == id);
                // if (index > -1) {
                //   // 发送更新的货品
                //   sendUpdateGoodsToServer({ goods: goods });

                //   console.log("2发送更新的goods:", "{ goods: goods }并删除goods", changeGoods[index]);
                //   changeGoods.splice(index, 1);
                // }
                let deletTemp = [];
                // 更新所有有商品的数据
                changeGoods.map((id) => {
                  const inputItem = inputWorkbenchList.find(({ goods, contractId }) => id == contractId && goods.length);
                  if (inputItem?.goods.length) {
                    sendUpdateGoodsToServer({ goods: inputItem.goods })
                    deletTemp.push(id);
                  }
                });
                deletTemp.map((id) => {
                  changeGoods.splice(changeGoods.findIndex(i => i == id), 1)
                })

              }
            })
          }

          // 商品详情的接口 获取合同id 和修改日期
          if (queryJson && queryJson["__Json_._LoadWFInfo"]) {
            response.text().then(res => {

              // 解析字符串形的对象
              const resData = eval("(" + res + ")");
              console.log(addList, "需要更新的入库列表");

              // 发送待入库列表到后台
              addList.map((item) => {

                const listItemKey = item.contractId + item.clientItemId + item.goodsCount + item.warehousedNumber + item.notWarehousedNumber + item.notWarehousedPackages;

                // resData.rows[0][0].trim() 合同ID
                if (item.contractId == resData.rows[0][0].trim()) {
                  console.log("发送入库列表", item.contractId)
                  sendContractListToServer(item).then(() => {
                    // 本地存储
                    // key 合同id+客户货号+合同数量+已入库数量+未入库数量+未入库件数   value 1
                    redis.setString(listItemKey, 1)
                  }).catch(error => {
                    console.log(error);
                  })
                }

              });

              // 服务端记录的修改时间
              const changeTime = new Date(resData.rows[0][12]).getTime();

              // key 合同id+time  value 修改时间
              const key = resData.rows[0][0].trim() + "time"

              // 获取本地存储的修改时间
              redis.getString(key).then(res => {
                // 本地没有代表首次或新增的数据 要保存到本地并更新
                if (!res) {
                  redis.setString(key, changeTime);
                  // 
                  console.log("changeGoods push的合同id:", resData.rows[0][0].trim());
                  changeGoods.push(resData.rows[0][0].trim());
                } else if (changeTime > res) {
                  console.log("被修改的合同id:", resData.rows[0][0].trim());
                  changeGoods.push(resData.rows[0][0].trim());
                  // 更新本地的修改时间
                  redis.setString(key, changeTime);
                  console.log("修改时间:", changeTime, "当前保存的时间:", res, "是否修改过", changeTime > res);
                }
              });
            })
          }
        }
      }
    })
  }

  // 监听页面请求
  function onPageList() {
    page.on("response", (response) => {
      if (response.status() == 200) {
        if (response.url().includes("27.15.50.G0.30.N9STJ.do.ui")) {

          // url query 参数转json
          const queryJson = urlQuery.parse(response.request().postData());

          // 当前组织代码 G118
          if (queryJson && queryJson.storagebatchno && queryJson.storagebatchno == "G118") {
            response.text().then(res => {
              // 解析字符串形的对象
              const resData = eval("(" + res + ")");
              // 存储的字段数组
              const fields = resData.fields;

              // 总数据条数
              totalItem = resData.rows.length;

              // 计算需要拖动滚动条几次
              totalpages = Math.floor(totalItem / count);

              resData.rows.map((item) => {

                let contractItem = {
                  "contractId": item[1].trim(), //采购合同号
                  "supplierName": getValueByNameId("ccode", item[5], fields), //供应商名称
                  "goodsName": item[9],//商品名称
                  "goodsCount": item[21],//合同数量
                  "transportId": item[7], //入库运编号
                  "clientItemId": item[8], //客户货号
                  "deliveryDate": item[30], //交货日期
                  "warehousedNumber": item[23],//已入库数量
                  "notWarehousedNumber": item[24],//未入库数量
                  "notWarehousedPackages": item[28],//未入库件数
                  "exportContractId": item[29],//出口合同号
                  "salesman": getValueByNameId("wcode", item[31], fields),//业务员
                  "department": getValueByNameId("bcode", item[37], fields),//部门
                  "operator": getValueByNameId("corpbcode", item[38], fields),//经营者
                  "goods": [],
                }

                inputWorkbenchList.push(contractItem);

                // key 合同id+客户货号+合同数量+已入库数量+未入库数量+未入库件数   value 1
                const key = (item[1].trim() + item[8] + item[21] + item[23] + item[24] + item[28]);

                redis.getString(key).then(res => {
                  // console.log(res);
                  if (!res) {
                    // 本地没有 需要更新
                    addList.push(contractItem);
                  }
                });
              })
              // 循环获取列表
              forList()
            })
          }
        }
      }
    })
  }

  /**
  * 
  * @param {*} name 字段标识
  * @param {*} Id 字段的id值
  * @param {*} array 所有的字段信息数组
  * @returns 匹配到的值
  */
  function getValueByNameId(name, Id, array) {
    let value = "";
    array.map((item) => {
      if (item.name == name) {
        value = item.valueMap[Id]
      }
    })
    return value
  }

  // 合同列表接口 发送数据
  function sendContractListToServer(data) {
    return new Promise((resole) => {
      const postData = JSON.stringify(data);
      // console.log(postData);
      const req = https.request({
        hostname: 'zhuyiyun.com',
        path: '/openapi/webhook/842298925882507267/842378384162422786',
        port: 443,
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'secretKey': '8b95cf4b511b49b2901272c4a1351b57'
        }
      }, (res) => {
        resole("ok")
        console.log("sendContractListToServer-发送合同列表-statusCode:", res.statusCode);
      });

      // 设置要发送的内容
      req.write(postData);
      // 如果出错就在控制台输出错误信息
      req.on('error', err => {
        console.log(err);
      });

      req.end();
    })
  }
  // 更新商品信息接口
  function sendUpdateGoodsToServer(data) {
    const postData = JSON.stringify(data);
    // console.log(postData);
    const req = https.request({
      hostname: 'zhuyiyun.com',
      path: '/openapi/webhook/842298925882507267/844579994607878146',
      port: 443,
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'secretKey': '8b95cf4b511b49b2901272c4a1351b57'
      }
    }, (res) => {
      console.log("sendUpdateGoodsToServer-发送货品-statusCode:", res.statusCode);
    });

    // 设置要发送的内容
    req.write(postData);
    // 如果出错就在控制台输出错误信息
    req.on('error', err => {
      console.log(err);
    });

    req.end();
  }

})();